package com.tensai.core.mvc.system.service.imp;

import com.alibaba.fastjson.JSON;
import com.tensai.core.mvc.base.service.imp.BaseIdServiceImpl;
import com.tensai.core.mvc.base.tools.XTree;
import com.tensai.core.mvc.system.dao.ISysMenuDao;
import com.tensai.core.mvc.system.entry.SysMenu;
import com.tensai.core.mvc.system.entry.SysUser;
import com.tensai.core.mvc.system.facade.UserMenu;
import com.tensai.core.mvc.system.service.ISysMenuService;
import com.tensai.core.utils.ObjectCheck;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 菜单service
 *
 * @author Tensai
 * 2018/12/21
 */
@Service
public class SysMenuService extends BaseIdServiceImpl<SysMenu, ISysMenuDao> implements ISysMenuService {

    @Autowired
    private ISysMenuDao sysMenuDao;

    @Override
    protected ISysMenuDao getDao() {
        return sysMenuDao;
    }

    /**
     * 获取当前用户的左侧菜单
     *
     * @return 当前用户左侧菜单
     */
    @Override
    public List<UserMenu> getUserMenus() {
        SysUser sysUser = getCurrentUser();
        List<Integer> checked = JSON.parseArray(sysUser.getSysGroup().getMenuJson(), Integer.class);
        List<SysMenu> sysMenuList1 = getDao().findByLevel(1);
        List<SysMenu> sysMenuList2 = getDao().findByLevel(2);
        List<SysMenu> sysMenuList3 = getDao().findByLevel(3);
        filterMenuList(checked, sysMenuList1, sysMenuList2, sysMenuList3);

        sysMenuList2 = mergeMenus(sysMenuList3, sysMenuList2);
        sysMenuList1 = mergeMenus(sysMenuList2, sysMenuList1);

        List<UserMenu> userMenuList = new ArrayList<>();
        sysMenuList1.forEach(item -> {
            UserMenu userMenu = new UserMenu(item);
            userMenuList.add(userMenu);
        });
        return userMenuList;
    }

    /**
     * 获取用户的菜单编辑树
     *
     * @param checkedList 菜单选中情况
     * @return 菜单编辑树
     */
    @Override
    public List<XTree> getUserMenus(List<Integer> checkedList) {
        List<SysMenu> sysMenuList1 = getDao().findByLevel(1);
        List<SysMenu> sysMenuList2 = getDao().findByLevel(2);
        List<SysMenu> sysMenuList3 = getDao().findByLevel(3);
        if (sysMenuList3 != null) {
            sysMenuList2 = mergeMenus(sysMenuList3, sysMenuList2);
        }
        if (sysMenuList2 != null) {
            sysMenuList1 = mergeMenus(sysMenuList2, sysMenuList1);
        }
        List<XTree> xTreeList = new ArrayList<>();
        sysMenuList1.forEach(item -> {
            XTree xTree = new XTree(item, checkedList);
            xTreeList.add(xTree);
        });
        return xTreeList;
    }

    @Override
    public List<SysMenu> findByType(String type) {
        return getDao().findByType(type);
    }

    /**
     * 两级菜单合并
     * @param source 子级菜单
     * @param target 父级菜单
     * @return 合并列表
     */
    private List<SysMenu> mergeMenus(List<SysMenu> source, List<SysMenu> target) {
        Set<SysMenu> sysMenuSet2 = new HashSet<>(target);
        target.clear();
        source.forEach(item ->
                sysMenuSet2.add(item.getParent())
        );
        target = new ArrayList<>(sysMenuSet2);
        List<SysMenu> finalTarget = target;
        source.forEach(sysMenu1 ->
                finalTarget.forEach(sysMenu0 -> {
                    if (sysMenu1.getParent().getId().equals(sysMenu0.getId())) {
                        if (sysMenu0.getSysMenuList() == null) {
                            sysMenu0.setSysMenuList(new ArrayList<>());
                        }
                        sysMenu0.getSysMenuList().add(sysMenu1);
                    }
                })
        );
        return finalTarget;
    }

    /**
     * 菜单过滤
     *
     * @param checked      拥有权限的菜单ID
     * @param sysMenuList1 一级菜单
     * @param sysMenuList2 二级菜单
     * @param sysMenuList3 三级菜单
     */
    private void filterMenuList(List<Integer> checked, List<SysMenu> sysMenuList1, List<SysMenu> sysMenuList2, List<SysMenu> sysMenuList3) {
        ObjectCheck.checkListAndInit(checked);
        ObjectCheck.checkListAndInit(sysMenuList1);
        ObjectCheck.checkListAndInit(sysMenuList2);
        ObjectCheck.checkListAndInit(sysMenuList3);
        sysMenuList1.removeIf(item -> !checked.contains(item.getId()));
        sysMenuList2.removeIf(item -> !checked.contains(item.getId()));
        sysMenuList3.removeIf(item -> !checked.contains(item.getId()));
    }

}

